package com.nuanshui.heatedloan.order.integration.execute.bizexecute;

import com.alibaba.dubbo.config.annotation.Reference;
import com.nuanshui.framework.exception.BizException;
import com.nuanshui.framework.exception.GlobalErrorCode;
import com.nuanshui.framework.utils.LogUtil;
import com.nuanshui.framework.utils.QRCodeUtil;
import com.nuanshui.framework.utils.redis.JedisUtil;
import com.nuanshui.heatedloan.baseservice.facade.AdvertisementService;
import com.nuanshui.heatedloan.baseservice.service.BaseServiceImpl;
import com.nuanshui.heatedloan.constant.DubboCacheRegion;
import com.nuanshui.heatedloan.constant.GlobalParam;
import com.nuanshui.heatedloan.dubbo.extension.cache.manager.DubboCacheManager;
import com.nuanshui.heatedloan.order.integration.bean.OrderResult;
import com.nuanshui.heatedloan.order.integration.execute.OrderExecute;
import com.nuanshui.heatedloan.order.integration.execute.handler.OrderHandler;
import com.nuanshui.heatedloan.order.integration.form.OrderExecuteForm;
import com.nuanshui.heatedloan.service.services.CommonTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 订单处理的基类，默认的一些操作会在这里执行，如果有不同的实现，继承这个类。
 * @Author: Gonzo
 * @Date 2017/3/1714:25
 * @since 1.4.2
 */
public abstract class AbstractOrderExecute extends BaseServiceImpl implements OrderExecute, OrderHandler {

	protected Logger logger = LoggerFactory.getLogger("appointment_order");

	// ------------------------------------------------------坑爹的dubbo，不支持注解加在父类上面......  /(ㄒoㄒ)/~~------------------------------------------------------
    private OrderHandler orderHandler;

	@Reference(url = GlobalParam.USER_DUBBO_SERVER, timeout = GlobalParam.DUBBO_SERVER_TIME_OUT,version = GlobalParam.USER_DUBBO_SERVER_VERSION)
	protected AdvertisementService advertisementService;

	@Autowired
	private CommonTool commonTool;

	@Autowired
	protected DubboCacheManager dubboCacheManager;

	protected Logger bizErrorLog = LoggerFactory.getLogger("order_biz_log");
	
	
	@Autowired
	private JedisUtil  jedisUtil;
	@Autowired
	private QRCodeUtil QRCodeUtil;

	/**
	 * 设置当前bizExecute的handlers
	 * @Author: Gonzo
	 * @Date 2017/3/23下午7:25
	 * @since 1.4.2
	 */
	@Override
	public  void setOrderHandler(OrderHandler handler){
		this.orderHandler = handler;
	}


	// -----------------------------------------------------子类必须要实现的方法-------------------------------------------------------------------------

	/**
	 * 执行取消订单
	 * @Author: Gonzo
	 * @Date 2017/3/1715:59
	 * @since 1.4.2
	 */
	protected abstract void doCancelOrder(OrderExecuteForm from, OrderResult result);

	
	/**
	 * 执行生成订单
	 * @Author: Gonzo
	 * @Date 2017/3/23下午7:24
	 * @since 1.4.2
	 */
	protected abstract void doPlaceOrder(OrderExecuteForm form, OrderResult result);

	/**
	 * 生成订单号
	 * @Author: Gonzo
	 * @Date 2017/3/23下午7:25
	 * @since 1.4.2
	 */
	protected abstract String generateOrderNum(OrderExecuteForm form);

	/**
	 * 在生成订单之前的一些操作
	 * Gonzo
	 * 2017年3月15日10:39:20
	 * @param form
	 * @param result
	 * @return
	 */
	protected abstract void beforePlaceOrder(OrderExecuteForm form, OrderResult result);


	/**
	 * 支付成功之后对订单的操作.
	 * 自雷如果有这个功能, 则复写
	 * @Author: Gonzo
	 * @Date 2017/4/14上午11:44
	 * @since 1.4.2
	 */
	protected OrderResult doPaySuccessOrder(OrderExecuteForm form, OrderResult result){
		return result;
	}

	/**
	 * 支付成功之后一些参数的封装
	 * @Author: Gonzo
	 * @Date 2017/4/18下午4:06
	 * @since 1.4.2
	 */
	protected void afterPaySuccessOrder(OrderExecuteForm form, OrderResult result) {

	}

	/**
	 * 订单超时未支付, 置为失效
	 * 这个只有收费的订单才会有这一步操作, 所以子类自行覆写.
	 * @Author: Gonzo
	 * @Date 2017/4/13上午9:58
	 * @since 1.4.2
	 */
	@Override
	public OrderResult overtimeOrder(OrderExecuteForm form){
		return new OrderResult();
	}


	/**
	 * 取消订单
	 * @Author: Gonzo
	 * @Date 2017/3/1715:46
	 * @since 1.4.2
	 */
	@Override
	public OrderResult cancelAppointmentOrderExecute(OrderExecuteForm form) {
		return this.orderHandler.cancelOrder(form, new OrderResult());
	}

	/**
	 * 生成订单
	 * @Author: Gonzo
	 * @Date 2017/4/13下午11:57
	 * @since 1.4.2
	 */
	@Override
	public OrderResult placeOrderExecute(OrderExecuteForm form){
		return this.orderHandler.placeOrder(form, new OrderResult());
	}
	
	/**
	 * 订单支付成功成之后
	 * @Author: Gonzo
	 * @Date 2017/4/14上午11:42
	 * @since 1.4.2
	 */
	@Override
	public OrderResult paySuccess(OrderExecuteForm form){
		return this.orderHandler.paySuccessOrder(form, new OrderResult());
	}

	/**
	 * 校验订单
	 * @Author: Gonzo
	 * @Date 2017/4/13下午11:58
	 * @since 1.4.2
	 */
	@Override
	public OrderResult verifyAppointmentQrcodeExecute(OrderExecuteForm from) {
		return this.orderHandler.verifyAppointmentOrder(from,   new OrderResult());
	}
	
	/**
	 * 订单支付成功之后, 发送的回调处理
	 * @Author: Gonzo
	 * @Date 2017/4/13下午11:58
	 * @since 1.4.2
	 */
	public OrderResult paySuccessOrderExecute(OrderExecuteForm from){
		return this.orderHandler.paySuccessOrder(from,   new OrderResult());
	}


	//------------------------------------------handler的方法-------------------------------------------------------------------------------------------------------------------------------------------------

	public void setNextOrderHandler(OrderHandler orderHandler){
		this.orderHandler = orderHandler;
	}


	@Override
	public OrderResult placeOrder(OrderExecuteForm form, OrderResult result){
 
		beforePlaceOrder(form, result);//生成订单之前的校验

		if (!result.isSuccess()) {
			return result;
		}
		doPlaceOrder(form, result);

		if (!result.isSuccess()) {
			return result;
		}

	   //给微信端生成二维码信息
//		LogUtil.info(logger, String.format("----------根据订单号为微信端生产二维码，订单的编号为 %s----------", form.getAppointmentOrderForm().getAppointmentOrderNum()));
//		UpLoadFileVO upLoadFileVO=QRCodeUtil.generateQRCode(form.getAppointmentOrderForm().getAppointmentOrderNum());
//		LogUtil.info(logger, String.format("----------根据订单号为微信端生产二维码，订单的编号为 %s----------", upLoadFileVO.getUrl()));
//		jedisUtil.del(CacheConstants.QRCODE_TYPE+ form.getAppointmentOrderForm().getAppointmentOrderNum());
//		jedisUtil.set(CacheConstants.QRCODE_TYPE+ form.getAppointmentOrderForm().getAppointmentOrderNum(), upLoadFileVO.getUrl());
		return result;
	}


	@Override
	public OrderResult paySuccessOrder(OrderExecuteForm form, OrderResult result){
		result = doPaySuccessOrder(form, result);
		if (!result.isSuccess()) {
			return result;
		}
		afterPaySuccessOrder(form, result);
		return result;
	}


	@Override
	public OrderResult cancelOrder(OrderExecuteForm form, OrderResult result){
		if(!result.isSuccess()) return result;

		//真正的取消
		doCancelOrder(form, result);

		//清缓存
		dubboCacheManager.evictCache(DubboCacheRegion.APPOIENT_USER_LIST);
		return result;
	}


	@Override
	public OrderResult verifyAppointmentOrder(OrderExecuteForm form, OrderResult result){

		if(!result.isSuccess()) return result;


		return result;
	}



	//----------------------------------------------父类提供的一些默认的公用方法--------------------------------------------------------------------------------------

	/**
	 * 抛一些业务异常。有时候不能返回dubboResponse对象，就只能抛异常了
	 * @Author: Gonzo
	 * @Date 2017/3/1717:12
	 * @since 1.4.2
	 */
	public void bizError(String msg) {
		LogUtil.info(bizErrorLog, msg);
		throw new BizException(GlobalErrorCode.UNKNOWN, msg);
	}
}
